package com.wywah.yunduo.security.supports.client;

import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Transient;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.util.SpringAuthorizationServerVersion;
import org.springframework.util.Assert;

import java.util.Collections;
import java.util.Map;

/**
 * 自定义客户端认证方式Token
 * @see org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken
 */
@Transient
public class YunduoOAuth2ClientSecretBasicAuthenticationToken extends YunduoAbstractAuthenticationToken {

    private static final long serialVersionUID;
    private final String clientId;
    private final RegisteredClient registeredClient;
    private final ClientAuthenticationMethod clientAuthenticationMethod;
    private final Object credentials;
    private final Map<String, Object> additionalParameters;

    public YunduoOAuth2ClientSecretBasicAuthenticationToken(String clientId, ClientAuthenticationMethod clientAuthenticationMethod, @Nullable Object credentials, @Nullable Map<String, Object> additionalParameters) {
        super(Collections.emptyList());
        Assert.hasText(clientId, "clientId cannot be empty");
        Assert.notNull(clientAuthenticationMethod, "clientAuthenticationMethod cannot be null");
        this.clientId = clientId;
        this.registeredClient = null;
        this.clientAuthenticationMethod = clientAuthenticationMethod;
        this.credentials = credentials;
        this.additionalParameters = Collections.unmodifiableMap(additionalParameters != null ? additionalParameters : Collections.emptyMap());
    }

    public YunduoOAuth2ClientSecretBasicAuthenticationToken(RegisteredClient registeredClient, ClientAuthenticationMethod clientAuthenticationMethod, @Nullable Object credentials) {
        super(Collections.emptyList());
        Assert.notNull(registeredClient, "registeredClient cannot be null");
        Assert.notNull(clientAuthenticationMethod, "clientAuthenticationMethod cannot be null");
        this.clientId = registeredClient.getClientId();
        this.registeredClient = registeredClient;
        this.clientAuthenticationMethod = clientAuthenticationMethod;
        this.credentials = credentials;
        this.additionalParameters = Collections.unmodifiableMap(Collections.emptyMap());
        this.setAuthenticated(true);
    }

    public Object getPrincipal() {
        return this.clientId;
    }

    @Nullable
    public Object getCredentials() {
        return this.credentials;
    }

    @Nullable
    public RegisteredClient getRegisteredClient() {
        return this.registeredClient;
    }

    public ClientAuthenticationMethod getClientAuthenticationMethod() {
        return this.clientAuthenticationMethod;
    }

    public Map<String, Object> getAdditionalParameters() {
        return this.additionalParameters;
    }

    static {
        serialVersionUID = SpringAuthorizationServerVersion.SERIAL_VERSION_UID;
    }
}
